/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sopra09.lv6659438.controller.autorenBearbeiten;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import sopra09.lv6659438.logik.autorenBearbeiten.AutorenBearbeitenALLocal;
import sopra09.lv6659438.objekte.Autor;
import sopra09.lv6659438.objekte.Buch;

/**
 * Initialisiert das Anzeigen der vorhandenen Systemautoren und verarbeitet die
 * vom Nutzer getroffene Auswahl. Verarbeitet neu eingegebene
 * Autoren. Verarbeitet das Löschen und Hinzufügen von Autoren für das gewählte Buch und übergibt
 * die ausgewählten Autoren (über den Session Scope) an den aufrufenden Anwendungsfall
 * 'Eintrag erfassen/Buch erfassen'.
 * @author TJ
 */
public class AutorenBearbeitenUCA extends de.fernunihagen.informatik.pi3.struts.UseCaseAction {
    
    /* forward name="success" path="" */    
    private final static String AUTOREN_ANZEIGEN = "autorenAnzeigen";
    private final static String AUTOREN_HINZUFUEGEN = "autorenHinzufuegen";
    private final static String NEUEN_AUTOR_ERFASSEN = "neuenAutorErfassen";
    private final static String BUCH_ERFASSEN = "buchErfassen";

    /**
     * Legt die Autoren des ausgewählten Buches im Session Scope ab.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */   
    public ActionForward initialisiereBuchautorenAnzeigen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("initialisiereBuchautorenAnzeigen(...) beginnt.");

        // das ausgewählte buch aus dem session scope auslesen
        Buch buch = (Buch) request.getSession().getAttribute("buch");

        log.warn("im Session-Scope finden sich folgende Attribute: \n" +
                "buch: " + buch.toString() +
                "mit den Feldern: \n" +
                "- buch.id: " +  buch.getId() + " \n" +
                "- buch.titel: " +  buch.getTitel() + " \n" +
                "- buch.jahr: " +  buch.getJahr() + " \n" +
                "- buch.autoren: " +  buch.getAutoren().toString() + " \n" +                
                "neu: " + request.getSession().getAttribute("neu")
                );

        //die autoren des buches im session scope ablegen
        request.getSession().setAttribute("autoren", buch.getAutoren());
        log.warn("buch.autoren wurde im attribut autoren im Session-Scope abgelegt: "
                + request.getSession().getAttribute("autoren").toString());

        // die attribute für die orientierungsleiste setzen
        request.getSession().setAttribute("AWF", "Autoren bearbeiten");
        request.getSession().setAttribute("AA", "Buchautoren anzeigen");

        log.warn("es wird an " + mapping.findForward(AUTOREN_ANZEIGEN).getPath() +
                " weitergeleitet.");
        return mapping.findForward(AUTOREN_ANZEIGEN);
    }

     /**
     * Initialisiert die Nutzer Aktion 'Neuen Autor erfassen'
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
       */
      public ActionForward initialisiereNeuenAutorErfassen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("initialisiereNeuenAutorErfassen(...) beginnt.");

        request.getSession().setAttribute("AWF", "Autoren bearbeiten");
        request.getSession().setAttribute("AA", "neuen Autor erfassen");

        log.warn("nach der Initialisierung wird an " + mapping.findForward(NEUEN_AUTOR_ERFASSEN).getPath() + " weitergeleitet");
        return mapping.findForward(NEUEN_AUTOR_ERFASSEN);
    }

     /**
     * Verarbeitet einen vom Nutzer eingegebenen neuen Autor.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
     public ActionForward verarbeiteNeuenAutor(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("verarbeiteNeuenAutor(...) beginnt.");

        // auslesen der eingegebenen attribute des neuen autors
        NeuenAutorErfassenVF vf = (NeuenAutorErfassenVF) form;
        String nachname = vf.getNachname();
        String vorname = vf.getVorname();
        int geburtsjahr = vf.getGeburtsjahr();

        // das ausgewählte buch aus dem session scope holen.
        Buch buch = (Buch) request.getSession().getAttribute("buch");

        log.warn("ein neuer Autor mit folgenden Eigenschaften wird erfasst: \n " +
                " - nachname: " + nachname + "\n" +
                " - vorname: " + vorname + "\n" +
                " - geburtsjahr: " + geburtsjahr + "\n" +
                " - buch: " + buch.toString()
                );

        // ein neues mit den übertragenen werten gefülltes autorobjekt in der anwendungslogik
        // anfordern
       InitialContext ic = new InitialContext();
       AutorenBearbeitenALLocal autorenBearbeiten = (AutorenBearbeitenALLocal) ic.lookup("java:comp/env/ejb/autorenBearbeiten");

       Autor autor = (Autor) autorenBearbeiten.liefereNeuenAutor(nachname, vorname, geburtsjahr, buch);

       // das angeforderte autorobjekt wurde erfolgreich empfangen
       if (autor != null) {
           log.warn("da (autor != null) " + (autor != null) +
                " ist, wird der Autor mit folgenden Eigenschaften der autorenListe im Session Scope hinzugefügt: \n" +
                "- nachname: " + autor.getNachname() + "\n" +
                "- vorname: " + autor.getVorname() + "\n" +
                "- name: " + autor.getName() + "\n" +
                "- geburtsjahr: " + autor.getGeburtsjahr() + "\n" +
                "- nameUndJahr: " + autor.getNameUndJahr() + "\n" +
                "- buecher: " + autor.getBuecher().toString());

           // die liste der systemautoren wird aus dem session scope geholt
           List autorenListe = (List) request.getSession().getAttribute("autorenListe");
           log.warn("autorenListe vor dem Hinzufügen: " + autorenListe.toString());

           // der neue autor wird der autorenliste hinzugefügt
           autorenListe.add(autor);
           log.warn("autorenListe nach dem Hinzufügen: " + autorenListe.toString());

           request.getSession().setAttribute("AWF", "Autoren bearbeiten");
           request.getSession().setAttribute("AA", "Autoren hinzufügen ");

            log.warn(" es wird an " + mapping.findForward(AUTOREN_HINZUFUEGEN).getPath() + " weitergeleitet");
            return mapping.findForward(AUTOREN_HINZUFUEGEN);

        //  das angeforderte autorobjekt wurde nicht empfangen
       } else {
          log.warn("da (autor != null) " + (autor != null) +
                " ist, wird an " + mapping.getInputForward().getPath() + " weitergeleitet" +
                " und fehlermeldung.neuenAutorErfassen ausgegeben");
          ActionMessages fehler = new ActionMessages();
          fehler.add("autorNichtErfasst", new ActionMessage("fehlermeldung.neuenAutorErfassen"));
          saveErrors(request, fehler);

          return mapping.getInputForward();

       }
    }

    /**
     * Entfernt einen vom Nutzer selektierten Autor aus der Autorenliste des ausgewählten
     * Buches.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward entferneSelektierteAutoren(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("entferneSelektierteAutoren(...) beginnt.");

        // benötigte session-attribute auslesen
        BuchautorenAnzeigenAF af = (BuchautorenAnzeigenAF) form;
        String[] selektierteAutoren = af.getSelektierteAutoren();
        Set<Autor> autoren = (Set<Autor>) request.getSession().getAttribute("autoren");
        // eine kopie der collection erstellen (zum iterieren)
        Set<Autor> kopieVonAutoren = new HashSet<Autor>(autoren);
        // einen neuen autor erstellen
        Autor autor = new Autor();

        log.warn("autoren im Session-Scope hat vor dem Entfernen folgende Größe: " +
                autoren.size());
        // es wurde mindestens ein autor selektiert
         if (selektierteAutoren != null) {
              log.warn(" es sind "+ selektierteAutoren.length + " Autoren zu entfernen: " );

              // das attribut nameUndJahr aller für das ausgewählte buch selektierter autoren
              //wird mit demselben attribut aller systemautoren verglichen.

              // über die zu entfernenden autoren iterieren
               for (int i = 0; i < selektierteAutoren.length; i++) {
                   log.warn("äussere for-schleife wird betreten");
                   String autorNameUndJahr =  (String) selektierteAutoren[i];
                   log.warn("autorNameUndJahr ist: " + autorNameUndJahr);

                   // über die (kopie von) buchautoren iterieren
                   Iterator itKopieVonAutoren = kopieVonAutoren.iterator();

                   while (itKopieVonAutoren.hasNext()){
                       log.warn("innere while-schleife wird betreten");                     
                       autor = (Autor) itKopieVonAutoren.next();
                       log.warn("autor ist: " + autor.getNameUndJahr());
                       log.warn("test:(autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr))ist "
                               + (autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr)));

                       // wenn beide attributwerte übereinstimmen, wird der selektierte autor
                       // aus der autorenliste des buches entfernt.
                       if (autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr)) {
                          log.warn("folgender Autor wird entfernt: " + autor.getNameUndJahr());
                           boolean erfolg = autoren.remove(autor);
                           log.warn("die Operation remove(autor) war erfolgreich : " + erfolg);
                           log.warn("autoren hat jetzt die Größe: " + autoren.size());
                       }
                   }
              }
        // es wurde kein autor selektiert
        } else {
          log.warn("da (selektierteAutoren != null) " + (selektierteAutoren != null) +
                " ist, wird an " + mapping.getInputForward().getPath() + " weitergeleitet" +
                " und fehlermeldung.entferneSelektierteAutoren ausgegeben");
          ActionMessages fehler = new ActionMessages();
          fehler.add("keinAutorZumEntfernenAusgewaehlt", new ActionMessage("fehlermeldung.entferneSelektierteAutoren"));
          saveErrors(request, fehler);

          return mapping.getInputForward();
        }
        return mapping.findForward(AUTOREN_ANZEIGEN);
    }

    /**
     * Initialisiert das Anzeigen aller Systemautoren, um den Nutzer das Hinzufügen
     * von Autoren zum ausgewählten Buch zu ermöglichen.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
   public ActionForward initialisiereAutorHinzufuegen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
       log.warn("initialisiereAutorHinzufuegen(...) beginnt.");

       // die liste aller systemautoren von der anwendungslogik anfordern
       InitialContext ic = new InitialContext();
       AutorenBearbeitenALLocal autorenBearbeiten = (AutorenBearbeitenALLocal) ic.lookup("java:comp/env/ejb/autorenBearbeiten");

       List<Autor> autorenListe = autorenBearbeiten.liefereAutorenliste();
       log.warn("eine Liste aller im System registrierter Autoren wurde angefordert: " +
               autorenListe.toString());
       // die angeforderte liste im session scope ablegen
       request.getSession().setAttribute("autorenListe", autorenListe);
       log.warn("die Liste wurde im Session-Scope im Attribut autorenListe abgelegt: \n " +
               request.getSession().getAttribute("autorenListe").toString());

       //Beginn Logging-Code
       List<Autor> autorenListeSessionScope = (List<Autor>)request.getSession().getAttribute("autorenListe");
       for (Autor autor : autorenListeSessionScope) {
            log.warn("Autor " + autor.getId() + " der autorenListe im Session-Scope hat folgende Attribute: \n " +
               "-Name: " + autor.getName()  + "\n" +
               "-Vorname: " + autor.getVorname() + "\n" +
               "-Nachname: " + autor.getNachname()  + "\n" +
               "-Geburtsjahr: " + autor.getGeburtsjahr()  + "\n" +
               "-Name und Jahr: " + autor.getNameUndJahr()  + "\n" +
               "-Buecher: " + autor.getBuecher().toString());
       }
       for (Autor autor : autorenListe) {
           Set<Buch> buecher = autor.getBuecher();
           Iterator it = buecher.iterator();
           while (it.hasNext()) {
               String testbuch = it.next().toString();
               log.warn("Buch ist: " + testbuch);
           }
       }
       // Ende Logging-Code

       request.getSession().setAttribute("AWF", "Autoren bearbeiten");
       request.getSession().setAttribute("AA", "Autoren hinzufügen ");

        return mapping.findForward(AUTOREN_HINZUFUEGEN);
    }

   /**
    * Verarbeitet die vom Nutzer zum Hinzufügen selektierten Autoren
    * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
    */
   public ActionForward verarbeiteAutorHinzufuegen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
       log.warn("verarbeiteAutorHinzufuegen(...) beginnt.");

       // vom nutzer ausgewählte autoren auselesen
       AutorenHinzufuegenAF af = (AutorenHinzufuegenAF) form;
       String[] hinzugefuegteAutoren = af.getHinzugefuegteAutoren();
       // benötigte attribute aus dem session-scope auslesen
       List<Autor> autorenListe = (List<Autor>) request.getSession().getAttribute("autorenListe");
       Set<Autor> autoren = (Set<Autor>) request.getSession().getAttribute("autoren");
       // einen neuen autor erzeugen
       Autor autor = new Autor();
      

       log.warn(" beteiligte Attribute: \n" +
               "- hinzugefuegteAutoren: " + hinzugefuegteAutoren + "\n" +
               "- autorenListe: " + autorenListe.toString() + "\n" +
               "- autoren: " + autoren.toString() + "\n"
               );

       // dem ausgewählten buch wurden autoren hinzugefügt
        if (hinzugefuegteAutoren != null) {
              // das attribut nameUndJahr aller hinzuzufügender autoren
              //wird mit demselben attribut aller systemautoren verglichen.

               // über die hinzuzufügenden autoren iterieren
               for (int i = 0; i < hinzugefuegteAutoren.length; i++) {
                   log.warn("äussere for-schleife wird betreten");
                   String autorNameUndJahr =  (String) hinzugefuegteAutoren[i];
                   log.warn("autorNameUndJahr ist: " + autorNameUndJahr);

                   // über die systemautoren iterieren
                   Iterator itAutorenListe = autorenListe.iterator();

                   while (itAutorenListe.hasNext()){
                       log.warn("innere while-schleife wird betreten");                     
                       autor = (Autor) itAutorenListe.next();
                       log.warn("autor ist: " + autor.getNameUndJahr());
                       log.warn("test:(autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr))ist " + (autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr)));

                       // wenn beide attributwerte übereinstimmen, wird der autor
                       // der autorenliste des buches hinzugefügt.
                       if (autor.getNameUndJahr().equalsIgnoreCase(autorNameUndJahr)) {
                          log.warn("folgender Autor wird hinzugefügt: " + autor.getNameUndJahr());                         
                           boolean erfolg = autoren.add(autor);
                           log.warn("die Operation add(autor) war erfolgreich : " + erfolg);
                           log.warn("autoren hat jetzt die Größe: " + autoren.size());
                       }
                   }
              }

        // es wurden keine autoren zum hinzufügen ausgewählt
        } else {
          log.warn("da (hinzugefuegteAutoren != null) " + (hinzugefuegteAutoren != null) +
                " ist, wird an " + mapping.getInputForward().getPath() + " weitergeleitet" +
                " und fehlermeldung.verarbeiteAutorHinzufuegen ausgegeben");
          ActionMessages fehler = new ActionMessages();
          fehler.add("keinAutorAusgewaehlt", new ActionMessage("fehlermeldung.verarbeiteAutorHinzufuegen"));
          saveErrors(request, fehler);

          return mapping.getInputForward();
        }

       log.warn("test, ob 'autoren' im Session Scope und 'autoren' Referenzen auf dasselbe Objekt sind: \n" +
                "((Object) request.getSession().getAttribute('autoren')) == autoren) ist " + ((Object)request.getSession().getAttribute("autoren") == autoren) + "\n" +
                "und gleichen Inhalt haben: \n" +
                "((Object) request.getSession().getAttribute('autoren')).equals(autoren)) ist " + (Object) request.getSession().getAttribute("autoren").equals(autoren));

       log.warn("autoren im Session-Scope enthält jetzt folgende Autoren: " +
               request.getSession().getAttribute("autoren").toString());
        log.warn("es wird an " + mapping.findForward(AUTOREN_ANZEIGEN).getPath() + " weitergeleitet");
        return mapping.findForward(AUTOREN_ANZEIGEN);
    }

   /**
    * Beendet die Bearbeitung von Autoren
    * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
    */
   public ActionForward beendeAutorenBearbeiten(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("beendeAutorenBearbeiten(...) beginnt.");

        // setzen von session attributen für die orientierungsleiste
        request.getSession().setAttribute("AWF", "Literatureintrag erfassen");
        request.getSession().setAttribute("AA", "Buch erfassen");

        // Beginn Logging-Code
        Buch buch = (Buch) request.getSession().getAttribute("buch");
        Set<Autor> autoren = (Set<Autor>) request.getSession().getAttribute("autoren");
        log.warn("test, ob 'buch.getAutoren' und 'autoren' Referenzen auf dasselbe Objekt sind: \n" +
                "(buch.getAutoren() == autoren) ist " + (buch.getAutoren() == autoren) + "\n" +
                "und gleichen Inhalt haben: \n" +
                "buch.getAutoren().equals(autoren) ist " + buch.getAutoren().equals(autoren));
           
        log.warn("das Buch mit dem bearbeiteten Autoren-Set befindet sich im Session Scope.");

        log.warn("es wird an " + mapping.findForward(BUCH_ERFASSEN).getPath() +
                " weitergeleitet.");
        //Ende Logging-Code

        return mapping.findForward(BUCH_ERFASSEN);
    }  
}
